-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.


local lu = require 'luaunit'
local c_sr_upgrade = require 'sr_upg_service.class.sr_upgrade'
local sr_upg_service = require 'sr_upg_service.sr_upg_service'
local client = require 'general_hardware.client'

TestSrUpgrade = {}

local DATA_PATH <const> = './test_data/sr_upgrade/'

function TestSrUpgrade:test_upgrade()
    -- MOCK二进制文件
    local bin_path = DATA_PATH .. 'test.bin'
    local storage_data = '\x01\x01\x01\x01\x01\x01\x01\x01'
    local file = io.open(bin_path, 'w+')
    -- csr_offset:128, Header:0-127 Data:128-143
    local test_data = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ..
                      '\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
    file:write(test_data)
    file:close()
    c_sr_upgrade.mds_obj = {}
    c_sr_upgrade.mds_obj.StorageChip = {
        Write = function (obj, ctx, offset, data)
            local s1 = string.sub(storage_data, 1, offset)
            local s2 = string.sub(storage_data, offset + #data + 1)
            storage_data = s1 .. data .. s2
        end,
        Read = function (obj, ctx, offset, length)
            return string.sub(storage_data, offset, length)
        end
    }
    -- 打桩器件加锁/解锁接口
    c_sr_upgrade.chip_lock = function ()
        return true, 0
    end
    c_sr_upgrade.chip_unlock = function ()
        return true, 0
    end
    c_sr_upgrade:upgrade(bin_path)
    local data_first_byte = string.unpack('B', storage_data, 129)
    local data_last_byte = string.unpack('B', storage_data, 144)
    lu.assertEquals(#storage_data, 144)
    lu.assertEquals(data_first_byte, 1)
    lu.assertEquals(data_last_byte, 1)

    os.execute('rm -f ' .. bin_path)
end

local g_sr_active_register_list = {}
local function stub_sr_upg_service_info(active_mode)
    client.FirmwareActiveFirmwareActiveRegisterActiveAction = function (_, _, sr_active_register_list)
        g_sr_active_register_list = sr_active_register_list
    end

    sr_upg_service.cfgs = {
        name = 'Firmware1',
        component_id = 1,
        component_id_ex = 2,
        board_id = 3
    }
    sr_upg_service.active_mode = active_mode
end

-- 测试CSR生效立即复位
function TestSrUpgrade:test_sr_active_mode_immediately()
    stub_sr_upg_service_info("Immediately")
    local ok = pcall(function()
        return sr_upg_service:on_upgrade_finish(_, 1, 'HWSR')
    end)

    local ps = {}
    for _, param in ipairs(g_sr_active_register_list) do
        ps[param.Key] = param.Value
    end
    lu.assertEquals(ok, true)
    lu.assertEquals('HWSR', ps.FirmwareId)
    lu.assertEquals('SR', ps.FirmwareType)
    lu.assertEquals('None', ps.ActiveCondition)
    lu.assertEquals('ResetBMC', ps.ActiveMode)
    lu.assertEquals('Ready', ps.ActiveStatus)
end

-- 测试CSR生效延迟复位
function TestSrUpgrade:test_sr_active_mode_reset_bmc()
    stub_sr_upg_service_info("ResetBMC")
    local ok = pcall(function()
        return sr_upg_service:on_upgrade_finish(_, 1, 'HWSR')
    end)

    local ps = {}
    for _, param in ipairs(g_sr_active_register_list) do
        ps[param.Key] = param.Value
    end
    lu.assertEquals(ok, true)
    lu.assertEquals('HWSR', ps.FirmwareId)
    lu.assertEquals('SR', ps.FirmwareType)
    lu.assertEquals('None', ps.ActiveCondition)
    lu.assertEquals('DelayResetBMC', ps.ActiveMode)
    lu.assertEquals('Ready', ps.ActiveStatus)
end
